package com.matrix.im.application;

import com.matrix.api.im.ImApi;
import com.matrix.api.im.dto.SystemMessageDTO;
import com.matrix.api.im.vo.SystemMessageVO;
import com.matrix.common.domain.PageResult;
import com.matrix.common.exception.BusinessException;
import com.matrix.im.converter.ImConverter;
import com.matrix.im.domain.model.SystemMessage;
import com.matrix.im.domain.repository.SystemMessageRepository;
import com.matrix.im.infrastructure.messaging.MessageBus;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 有点甜
 * @since 2025/8/2
 */
@Service
@DubboService
@RequiredArgsConstructor
public class SystemMessageAppService implements ImApi {

    private final SystemMessageRepository systemMessageRepository;
    private final MessageBus messageBus;

    @Override
    @Transactional
    public void sendSystemMessage(SystemMessageDTO dto) {
        SystemMessage message = SystemMessage.create(
                dto.getUserId(),
                dto.getTitle(),
                dto.getContent(),
                dto.getType(),
                dto.getRelatedId()
        );

        systemMessageRepository.save(message);

        messageBus.publishSystemMessage(message);
    }

    public PageResult<SystemMessageVO> getSystemMessages(Long userId, int pageNum, int pageSize) {
        Page<SystemMessage> page = systemMessageRepository.findByUserId(userId, pageNum, pageSize);
        List<SystemMessageVO> voList = page.getContent().stream()
                .map(ImConverter.INSTANCE::toSystemMessageVO)
                .collect(Collectors.toList());
        return new PageResult<>(voList, page.getTotalElements(), page.getTotalPages());
    }

    @Transactional
    public void markAsRead(Long userId, String messageId) {
        SystemMessage message = systemMessageRepository.findById(messageId)
                .orElseThrow(() -> new BusinessException("消息不存在"));

        message.markAsRead(userId);

        systemMessageRepository.save(message);
    }

    public long getUnreadCount(Long userId) {
        return systemMessageRepository.countUnread(userId);
    }
}
